#include <iostream>
#include <string>
#include <cstring>
#include <memory>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include "TcpServer.hpp"
#include "Interpret.hpp"
#include "ThreadPool.hpp"
#include "Daemon.hpp"
#include <algorithm>

Interpret trans;

void Usage(const std::string &proc)
{
    std::cout << "Usage:" << proc << " tcp_port" << std::endl;
}

void Interact(int sockfd, std::string &out, const std::string &in)
{
    char buffer[1024];
    ssize_t n = read(sockfd, buffer, sizeof(buffer) - 1);
    if (n > 0)
    {
        buffer[n] = 0;
        write(sockfd, in.c_str(), in.size()); // 将pong内容写给客户端
    }
    else if (n == 0) // 如果读取到0了，说明读到文件结尾了，说明客户端退出了
    {
        lg.LogMessage(Info, "client quit...\n");
    }
    else
    {
        lg.LogMessage(Error, "read socket error, errno code: %d, error string: %s\n", errno, strerror(errno));
    }
}
// 未来的服务器是部署在云服务器上的，你怎么知道你的服务器是健康的呢？
// 我们可以定期（30s）向服务器发送一个最小的请求，如果得到了回复，说明是健康的
// 这个机制叫做心跳机制，client -> server，或者 反向server->client
void Ping(int sockfd, Inet_Addr addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd: %d\n", addr.PrintDebug().c_str(), "ping", sockfd);
    std::string message;
    Interact(sockfd, message, "pong");
}

void Translate(int sockfd, Inet_Addr addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd: %d\n", addr.PrintDebug().c_str(), "Translate", sockfd);
    char buffer[1024];
    ssize_t n = read(sockfd, buffer, sizeof(buffer) - 1);
    if (n > 0)
    {
        buffer[n] = 0;
    }
    std::string chinese = trans.Excute(buffer);
    write(sockfd, chinese.c_str(), chinese.size()); // 将pong内容写给客户端
    lg.LogMessage(Debug, "%s Translate Service,%s->%s\n", addr.PrintDebug().c_str(), buffer, chinese.c_str());
}

void Transform(int sockfd, Inet_Addr addr)
{
    lg.LogMessage(Debug, "%s select %s success, fd: %d\n", addr.PrintDebug().c_str(), "Transform", sockfd);
    char buffer[1024];
    ssize_t n = read(sockfd, buffer, sizeof(buffer) - 1);
    if (n > 0)
    {
        buffer[n] = 0;
    }
    std::string result = buffer;
    std::transform(result.begin(), result.end(), result.begin(), [](char c)
                   { return std::toupper(c); });
    write(sockfd, result.c_str(), result.size()); // 将pong内容写给客户端
    lg.LogMessage(Debug, "%s transform Service,%s->%s\n", addr.PrintDebug().c_str(), buffer, result.c_str());
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        return 1;
    }
    int port = std::stoi(argv[1]);
    Daemon(false, false);
    lg.Enable(Classfile);
    std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>(port);
    tsvr->RegisterFunc("ping", Ping);
    tsvr->RegisterFunc("translate", Translate);
    tsvr->RegisterFunc("transform", Transform);

    tsvr->Init();
    tsvr->Start();

    return 0;
}